﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.IO;
using System.Xml;
using RazorEngine;


namespace pgnSoft.Veloz.ERP.Controllers
{
    public class MainController : System.Web.Mvc.Controller
    {

        public ActionResult Index(string lang)
        {
            if (lang == "favicon.ico")
            {
                return null;
            }
            else
            {
                Models.PageModel model = new Models.PageModel(this);
                if (!string.IsNullOrWhiteSpace(lang) && lang != "null")
                {
                    model.CurrentCultureInfo = new System.Globalization.CultureInfo(lang);
                }
                return View(model);
            }
        }


        public string Style(string filename)
        {
            Response.ContentType = "text/css";
            string global = "";
            string fileGlobal =   System.IO.Path.GetDirectoryName(Server.MapPath(filename)) + "\\global.js";
            if (System.IO.File.Exists( fileGlobal))
            {
                global = "@{\r\n" + System.IO.File.ReadAllText(fileGlobal) + "\r\n}\r\n";
            }
            return Razor.Parse(global + System.IO.File.ReadAllText(Server.MapPath(filename)).Replace("@media ", "#media ").Replace("@font-face ", "#font-face ").Replace("@keyframes ", "#keyframes ").Replace("@-webkit-", "#-webkit-").Replace("@-o-", "#-o-").Replace("@-ms-", "#-ms-")).Replace("#media ", "@media ").Replace("#font-face ", "@font-face ").Replace("#keyframes ", "@keyframes ").Replace("#-webkit-", "@-webkit-").Replace("#-o-", "@-o-").Replace("#-ms-", "@-ms-");
        }

        [OutputCache(Duration = 3600)]
        public ActionResult GetExamplesNodes(string node)
        {
            if (node == "Root")
            {
                return null;
               // return this.Content(ExamplesModel.GetExamplesNodes().ToJson());
            }

            return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
        }

        //public DirectResult GetThemeUrl(string theme, bool reload)
        //{
        //    Theme temp = (Theme)Enum.Parse(typeof(Theme), theme);

        //    this.Session["Ext.Net.Theme"] = temp;

        //    if (reload)
        //    {
        //        X.Reload();
        //        return this.Direct();
        //    }

        //    return this.Direct(MvcResourceManager.GetThemeUrl(temp));
        //}

        //[OutputCache(Duration = 86400, VaryByParam = "name")]
        //public DirectResult GetHashCode(string name)
        //{
        //    return this.Direct(Math.Abs(name.ToLower().GetHashCode()));
        //}

        //public DirectResult ChangeScriptMode(bool debug)
        //{
        //    if (debug)
        //    {
        //        this.Session["Ext.Net.ScriptMode"] = Ext.Net.ScriptMode.Debug;
        //        this.Session["Ext.Net.SourceFormatting"] = true;
        //    }
        //    else
        //    {
        //        this.Session["Ext.Net.ScriptMode"] = Ext.Net.ScriptMode.Release;
        //        this.Session["Ext.Net.SourceFormatting"] = false;
        //    }

        //    Response.Redirect("");

        //    return this.Direct();
        //}

    }



    public class ExamplesModel
    {
        internal static string ExamplesRoot = "~/Modulos/";

        public static object GetExamplesNodes()
        {
            //string nodes = "";//new NodeCollection();
           // string path = HttpContext.Current.Server.MapPath(ExamplesModel.ExamplesRoot);

            return null;// ExamplesModel.BuildAreasLevel();
        }

        public static string ApplicationRoot
        {
            get
            {
                string root = HttpContext.Current.Request.ApplicationPath;
                return root == "/" ? "" : root;
            }
        }

        private static readonly string[] excludeList = { ".svn", "_svn", "Shared" };

        private static object BuildAreasLevel()
        {
            string path = HttpContext.Current.Server.MapPath(ExamplesModel.ExamplesRoot);
            DirectoryInfo root = new DirectoryInfo(path);
            DirectoryInfo[] folders = root.GetDirectories();
            folders = ExamplesModel.SortFolders(root, folders);

            //NodeCollection nodes = new NodeCollection(false);
            object nodes;// = new NodeCollection(false);

            foreach (DirectoryInfo folder in folders)
            {
                if ((folder.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden ||
                    excludeList.Contains(folder.Name) || folder.Name.StartsWith("_"))
                {
                    continue;
                }

                ExampleConfig cfg = new ExampleConfig(folder.FullName + "\\config.xml");

                string iconCls = string.IsNullOrEmpty(cfg.IconCls) ? "" : cfg.IconCls;
                //Node node = null;
                var index = folder.Name.IndexOf('_');

                if (cfg.MainGroup || index < 0)
                {
                    //node = new Node();
                    //node.NodeID = BaseControl.GenerateID();
                    //node.Text = folder.Name.Replace("_", " ");

                    //nodes.Add(node);

                    //node.IconCls = iconCls;
                    if (ExamplesModel.IsNew(folder.FullName))
                    {
                        //node.CustomAttributes.Add(new ConfigItem("isNew", "true", ParameterMode.Raw));
                    }
                }
                else
                {
                    var mainGroupName = folder.Name.Substring(0, index);
                   // node = nodes.FirstOrDefault(n => n.Text == mainGroupName);

                    //if (node == null)
                    //{
                        //node = new Node();
                        //node.NodeID = BaseControl.GenerateID();
                        //node.Text = mainGroupName;
                        //nodes.Add(node);
                   // }

                    if (!string.IsNullOrWhiteSpace(iconCls))
                    {
                        //node.IconCls = iconCls;
                    }

                    //if (ExamplesModel.IsNew(folder.FullName) && !node.CustomAttributes.Contains("isNew"))
                    //{
                        //node.CustomAttributes.Add(new ConfigItem("isNew", "true", ParameterMode.Raw));
                    //}

                    object groupNode;// = new Node();

                    //groupNode.NodeID = BaseControl.GenerateID();
                   // groupNode.Text = folder.Name.Substring(index + 1).Replace("_", " ");

                    //if (ExamplesModel.IsNew(folder.FullName) && !groupNode.CustomAttributes.Contains("isNew"))
                    //{
                    //    groupNode.CustomAttributes.Add(new ConfigItem("isNew", "true", ParameterMode.Raw));
                    //}

                    //node.Children.Add(groupNode);
                   // node = groupNode;
                }

                //ExamplesModel.BuildViewsLevel(folder, node);
            }

            return null;//return nodes;
        }

        private static void BuildViewsLevel(DirectoryInfo area, object areaNode)
        {
            DirectoryInfo[] folders = new DirectoryInfo(area.FullName + "\\Views").GetDirectories();

            folders = ExamplesModel.SortFolders(area, folders);

            foreach (DirectoryInfo folder in folders)
            {
                if ((folder.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden ||
                    excludeList.Contains(folder.Name) || folder.Name.StartsWith("_"))
                {
                    continue;
                }

                ExampleConfig cfg = new ExampleConfig(folder.FullName + "\\config.xml");

                string iconCls = string.IsNullOrEmpty(cfg.IconCls) ? "" : cfg.IconCls;
                //Node node = new Node();

                string folderName = folder.Name.Replace("_", " ");

               // node.Text = folderName;

                if (ExamplesModel.IsNew(folder.FullName))
                {
                    //node.CustomAttributes.Add(new ConfigItem("isNew", "true", ParameterMode.Raw));
                }

                //node.IconCls = iconCls;
                string url = string.Concat(ExamplesModel.ApplicationRoot, "/", area.Name, "/", folder.Name, "/");
                //node.NodeID = "e" + Math.Abs(url.ToLower().GetHashCode());
                //node.Href = url;

                //node.Leaf = true;

                //node.CustomAttributes.Add(new { tags = cfg.Tags.Select(item => item.ToLower()) });

                //areaNode.Children.Add(node);
            }
        }

        private static ExampleConfig rootCfg;

        private static bool IsNew(string folder)
        {
            if (ExamplesModel.rootCfg == null)
            {
                ExamplesModel.rootCfg = new ExampleConfig(new DirectoryInfo(HttpContext.Current.Server.MapPath(ExamplesModel.ExamplesRoot)) + "\\config.xml");
            }

            foreach (string newFolder in rootCfg.NewFolders)
            {
                string newPath = string.Concat(HttpContext.Current.Server.MapPath(ExamplesModel.ExamplesRoot), newFolder);

                if (newPath.StartsWith(folder, StringComparison.CurrentCultureIgnoreCase))
                {
                    string end = newPath.Substring(folder.Length);

                    if ((end.StartsWith("\\") || end.Equals("")))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        private static DirectoryInfo[] SortFolders(DirectoryInfo root, DirectoryInfo[] folders)
        {
            string cfgPath = root.FullName + "\\config.xml";

            if (File.Exists(root.FullName + "\\config.xml"))
            {
                ExampleConfig rootCfg = new ExampleConfig(cfgPath);

                if (rootCfg.OrderFolders.Count > 0)
                {
                    List<DirectoryInfo> list = new List<DirectoryInfo>(folders);
                    int pasteIndex = 0;

                    foreach (string orderFolder in rootCfg.OrderFolders)
                    {
                        int dIndex = 0;

                        for (int ind = 0; ind < list.Count; ind++)
                        {
                            if (list[ind].Name.ToLower() == orderFolder)
                            {
                                dIndex = ind;
                            }
                        }

                        if (dIndex > 0)
                        {
                            DirectoryInfo di = list[dIndex];
                            list.RemoveAt(dIndex);
                            list.Insert(pasteIndex++, di);
                        }
                    }

                    folders = list.ToArray();
                }
            }

            return folders;
        }
    }

    public class ExampleConfig
    {
        private string path;

        public ExampleConfig(string path)
        {
            this.path = path;
            this.Load();
        }

        private void Load()
        {
            this.Description = "No description";
            XmlDocument xml = new XmlDocument();

            if (File.Exists(path))
            {
                try
                {
                    xml.Load(path);
                }
                catch (FileNotFoundException)
                {
                    return;
                }
            }

            XmlNode root = xml.SelectSingleNode("example");

            if (root == null)
            {
                return;
            }

            XmlAttribute iconCls = root.Attributes["iconCls"];

            if (iconCls != null)
            {
                this.IconCls = iconCls.Value;
            }

            XmlAttribute mainGroup = root.Attributes["group"];

            if (mainGroup != null)
            {
                this.MainGroup = mainGroup.Value == "1";
            }

            XmlNode desc = root.SelectSingleNode("description");

            if (desc != null)
            {
                this.Description = desc.InnerText;
            }

            XmlNodeList folders = root.SelectNodes("order/folder");

            if (folders != null)
            {
                foreach (XmlNode folder in folders)
                {
                    XmlAttribute urlAttr = folder.Attributes["name"];

                    if (urlAttr != null && !string.IsNullOrEmpty(urlAttr.InnerText))
                    {
                        string folderName = urlAttr.InnerText;
                        this.OrderFolders.Add(folderName.ToLower());
                    }
                }
            }

            folders = root.SelectNodes("new/folder");

            if (folders != null)
            {
                foreach (XmlNode folder in folders)
                {
                    XmlAttribute urlAttr = folder.Attributes["name"];

                    if (urlAttr != null && !string.IsNullOrEmpty(urlAttr.InnerText))
                    {
                        string folderName = urlAttr.InnerText;
                        this.NewFolders.Add(folderName.ToLower());
                    }
                }
            }

            XmlNode tagsNode = root.SelectSingleNode("tags");

            if (tagsNode != null)
            {
                this.Tags.AddRange(tagsNode.InnerText.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
            }
        }

        public string IconCls { get; private set; }

        public bool MainGroup { get; private set; }

        public string Title { get; private set; }

        public string Description { get; private set; }

        private List<string> orderFolders;
        public List<string> OrderFolders
        {
            get
            {
                if (this.orderFolders == null)
                {
                    this.orderFolders = new List<string>();
                }
                return this.orderFolders;
            }
        }

        private List<string> newFolders;
        public List<string> NewFolders
        {
            get
            {
                if (this.newFolders == null)
                {
                    this.newFolders = new List<string>();
                }
                return this.newFolders;
            }
        }

        private List<string> tags;
        public List<string> Tags
        {
            get
            {
                if (this.tags == null)
                {
                    this.tags = new List<string>();
                }
                return this.tags;
            }
        }
    }
}
